package com.example.javamediaserver.rtmp;

import com.example.javamediaserver.model.StreamSession;
import com.example.javamediaserver.service.StreamSessionService;
import io.antmedia.rtmp.IRTMPApplication;
import io.antmedia.rtmp.RTMPConnection;
import io.antmedia.rtmp.stream.IRTMPStream;
import io.antmedia.rtmp.stream.IStreamListener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 自定义 RTMP 应用适配器
 * 实现了 Ant Media RTMP 库的 IRTMPApplication 接口，
 * 用于处理 RTMP 连接、发布、播放等事件，并桥接到我们自己的业务逻辑。
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class RtmpApplicationAdapter implements IRTMPApplication {

    private final StreamSessionService streamSessionService;

    // --- IRTMPApplication 接口方法实现 ---

    @Override
    public boolean appStart(String applicationName) {
        log.info("RTMP Application '{}' started.", applicationName);
        // 通常返回 true 表示应用启动成功
        return true;
    }

    @Override
    public void appStop(String applicationName) {
        log.info("RTMP Application '{}' stopped.", applicationName);
    }

    @Override
    public boolean appConnect(RTMPConnection conn, Object[] params) {
        log.info("RTMP client connected: {}", conn.getSessionId());
        // 这里可以进行连接认证等操作
        // 返回 true 表示允许连接
        return true;
    }

    @Override
    public void appDisconnect(RTMPConnection conn) {
        log.info("RTMP client disconnected: {}", conn.getSessionId());
        // 当客户端断开连接时，结束会话记录
        streamSessionService.endSession(conn.getSessionId());
    }

    @Override
    public boolean publish(RTMPConnection conn, String streamName, String mode) {
        log.info("RTMP stream published: App={}, Name={}, Mode={}", conn.getAppName(), streamName, mode);

        // 创建并保存会话记录
        StreamSession streamSession = new StreamSession();
        streamSession.setId(conn.getSessionId()); // 使用连接ID作为会话ID
        streamSession.setStreamPath(conn.getAppName() + "/" + streamName); // 组合完整的流路径
        streamSession.setClientIp(conn.getRemoteAddress());
        // conn.getConnectParams() 可能包含客户端信息，需要检查具体内容
        // streamSession.setClientInfo(getClientInfo(conn.getConnectParams()));
        streamSession.setStartTime(java.time.LocalDateTime.now());
        streamSession.parseStreamPath(); // 解析 app 和 streamKey

        streamSessionService.saveSession(streamSession);

        // 返回 true 表示允许发布
        return true;
    }

    @Override
    public void unpublish(RTMPConnection conn, String streamName) {
        log.info("RTMP stream unpublished: App={}, Name={}", conn.getAppName(), streamName);
        // 理论上 unpublish 后连接可能仍然存在，但通常也意味着流结束
        // 在 appDisconnect 中处理会话结束更可靠
        // streamSessionService.endSession(conn.getSessionId());
    }

    // --- 其他 IRTMPApplication 接口方法 (根据需要实现) ---

    @Override
    public boolean play(RTMPConnection conn, String streamName, long start, long length, boolean flushPlaylist) {
        log.info("RTMP play request: App={}, Name={}, Start={}, Len={}, Flush={}",
                 conn.getAppName(), streamName, start, length, flushPlaylist);
        // 如果需要支持 RTMP 拉流播放，需要实现这里的逻辑
        // 通常是查找对应的发布流并开始发送数据给该连接
        // 返回 true 表示允许播放
        return true; // 暂时允许所有播放请求
    }

    @Override
    public void pause(RTMPConnection conn, String streamName, int pausedAt) {
        log.info("RTMP pause request: App={}, Name={}, At={}", conn.getAppName(), streamName, pausedAt);
        // 处理播放暂停
    }

    @Override
    public void resume(RTMPConnection conn, String streamName, int resumedAt) {
         log.info("RTMP resume request: App={}, Name={}, At={}", conn.getAppName(), streamName, resumedAt);
        // 处理播放恢复
    }


    @Override
    public void seek(RTMPConnection conn, String streamName, int position) {
         log.info("RTMP seek request: App={}, Name={}, Pos={}", conn.getAppName(), streamName, position);
        // 处理播放跳转
    }

    @Override
    public void stop(RTMPConnection conn, String streamName) {
         log.info("RTMP stop request: App={}, Name={}", conn.getAppName(), streamName);
         // 处理播放停止
    }

    @Override
    public void streamStarted(String streamName) {
         log.info("RTMP stream started internally: {}", streamName);
         // 流开始的内部事件
    }

    @Override
    public void streamStopped(String streamName) {
        log.info("RTMP stream stopped internally: {}", streamName);
        // 流停止的内部事件
    }

     @Override
     public void streamPublishStart(IRTMPStream stream) {
         log.info("Stream publish started: {}", stream.getName());
         stream.addStreamListener(new StreamListenerImpl(stream.getStreamId()));
     }

     @Override
     public void streamRecordStart(IRTMPStream stream) {
         log.info("Stream record started: {}", stream.getName());
     }

     @Override
     public void streamRecordStop(IRTMPStream stream) {
         log.info("Stream record stopped: {}", stream.getName());
     }

     // --- Helper Methods (if needed) ---

     private String getClientInfo(Map<String, Object> connectParams) {
         // 从连接参数中提取客户端信息，例如 Flash Version, swfUrl 等
         // 需要根据实际的 connectParams 内容进行解析
         return connectParams != null ? connectParams.toString() : null;
     }

    /**
     * 简单的流监听器实现，用于日志记录或其他流事件处理
     */
    @Slf4j
    private static class StreamListenerImpl implements IStreamListener {
        private final String streamId;

        public StreamListenerImpl(String streamId) {
            this.streamId = streamId;
        }

        @Override
        public void onStreamPublished() {
            log.debug("Stream [{}] listener: Published", streamId);
        }

        @Override
        public void onStreamUnpublished() {
            log.debug("Stream [{}] listener: Unpublished", streamId);
        }

        @Override
        public void onStreamClosed() {
            log.debug("Stream [{}] listener: Closed", streamId);
        }

        @Override
        public void onStreamPaused() {
             log.debug("Stream [{}] listener: Paused", streamId);
        }

        @Override
        public void onStreamResumed() {
            log.debug("Stream [{}] listener: Resumed", streamId);
        }

        @Override
        public void onStreamPlayed() {
            log.debug("Stream [{}] listener: Played", streamId);
        }

         @Override
         public void onStreamStopped() {
             log.debug("Stream [{}] listener: Stopped Playing", streamId);
         }

         @Override
         public void onStreamSeeked() {
             log.debug("Stream [{}] listener: Seeked", streamId);
         }
    }
} 